import Ball from "./Ball";
import Barrier from "./Barrier";
import Config from "./Config";

// Learn TypeScript:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const { ccclass, property } = cc._decorator;

@ccclass
export default class MainController extends cc.Component {
    // 弹球父节点
    @property(cc.Node)
    contentView: cc.Node = null;
    // 失败
    @property(cc.Node)
    GameOverView: cc.Node
    // 是否失败
    isGameOver: boolean = false;
    // 预制 资源中的 ball
    @property(cc.Prefab)
    prefabBall: cc.Prefab = null;
    // 预制 障碍物数组
    @property([cc.Prefab])
    prefabBarriers: cc.Prefab[] = [];
    // 球 数组
    @property([Ball])
    balls: Ball[] = [];
    // 障碍物数组
    barriers: Barrier[] = [];
    // 分数 label
    @property(cc.Label)
    lbScoreCount: cc.Label = null;
    // 得分
    score: number = -1;
    // 回收球的个数
    recvcleBallsCount: number = 1;
    // 层数
    layerNumber: number = 0;

    onLoad() {

        this.addScore();

        this.addBarriers();

        // 事件监听
        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this)

        // 初始化 第一个球
        this.balls[0].main = this;
        this.balls[0].node.group = Config.groupBallIngGame;
    }

    start() {

    }

    update(dt: number) {

    }

    // 监听点击 事件
    onTouchStart(touch: cc.Event.EventTouch) {
        if (!this.isRecycleFinsh() || this.isGameOver) { return; }
        //  重置回收球的个数
        this.recvcleBallsCount = 0;
        let touchPos = this.node.convertTouchToNodeSpaceAR(touch.touch);
        cc.log(JSON.stringify(touchPos));
        // 发射球
        this.shootBalls(touchPos.sub(cc.v2(0, 493)));
    }

    shootBalls(dir: cc.Vec2) {
        for (var i = 0; i < this.balls.length; i++) {
            let ball = this.balls[i];
            this.scheduleOnce(function () {
                this.shootBall(ball, dir);
            }.bind(this), i * 0.2);
        }
    }

    shootBall(ball: Ball, dir: cc.Vec2) {
        ball.rigidBody.active = false;
        ball.node.group = Config.groupBallIngGame;

        let poses: cc.Vec2[] = [];
        poses.push(ball.node.position);
        poses.push(cc.v2(0, 423));

        ball.node.runAction(cc.sequence(cc.cardinalSplineTo(0.8, poses, 0.5), cc.callFunc(function () {
            ball.rigidBody.active = true;
            ball.rigidBody.linearVelocity = dir.mul(4);
        })));
    }

    // 添加障碍物
    addBarriers() {
        let startPosX = -305;
        let endPosX = 295 - this.getRandomSpace();
        // 没个障碍物 之间的间隔计算
        let currentPosX = startPosX + this.getRandomSpace();

        while (currentPosX < endPosX) {
            let barrier = cc.instantiate(this.prefabBarriers[Math.floor(Math.random() * this.prefabBarriers.length)]).getComponent<Barrier>(Barrier);
            barrier.getRandomScore(this.layerNumber*6)
            barrier.node.parent = this.contentView;
            barrier.main = this;
            barrier.node.rotation = Math.random() * 360;
            barrier.node.position = cc.v2(currentPosX, -400);
            // 调整间隔
            currentPosX += barrier.node.width * 1.3;
            currentPosX += this.getRandomSpace();
            this.barriers.push(barrier);
        }
        // 层数 +1
        this.layerNumber += 1;
    }

    removeBarrier(barrier: Barrier) {
        let idx = this.barriers.indexOf(barrier);
        if (idx != -1) {
            barrier.node.removeFromParent(false);
            this.barriers.splice(idx, 1);
        }
    }

    // 添加 ball
    addBall(pos: cc.Vec2) {
        let ball = cc.instantiate(this.prefabBall).getComponent<Ball>(Ball);
        ball.node.parent = this.node;
        ball.node.position = pos;
        ball.main = this;
        ball.node.group = Config.groupBallIngGame;
        this.balls.push(ball);
    }

    // 回收 ball 并且判断是否失败
    recycleBall() {
        this.recvcleBallsCount++;
        if (this.isRecycleFinsh()) {
            for (var i = 0; i < this.barriers.length; i++) {
                let barrier = this.barriers[i];
                if (barrier.node.y > 320) {
                    cc.log('你失败了')
                    this.isGameOver = true;
                    this.GameOverView.active = true;
                    return;
                } else {
                    console.log(barrier.node.y)
                }
                barrier.node.runAction(cc.moveBy(0.5, cc.v2(0, 110)));
            }
            this.addBarriers();
        }
    }

    isRecycleFinsh(): boolean {
        return this.recvcleBallsCount == this.balls.length;
    }

    // 积分
    addScore() {
        this.score += 1;
        this.lbScoreCount.string = this.score.toString();
    }

    getRandomSpace(): number {
        return 70 + Math.random() * 30;
    }

    // 失败逻辑
    agaginGame() {
        // 隐藏 失败面板
        this.GameOverView.active = false;
        // 清零分数
        this.score = 0;
        this.lbScoreCount.string = "0";
        // 重置层数
        this.layerNumber = 1;
        // 重置障碍物
        for (const key in this.barriers) {
            if (this.barriers.hasOwnProperty(key)) {
                const element = this.barriers[key];
                element.node.removeFromParent(false);
            }
        }
        this.barriers.splice(0, this.barriers.length);
        this.addBarriers();

        // 重置球的个数
        for (const key in this.balls) {
            if (key == "0") { continue; }
            if (this.balls.hasOwnProperty(key)) {
                const element = this.balls[key];
                element.node.removeFromParent(false);
            }
        }
        this.balls = this.balls.slice(0, 1);
        //  重置回收球的个数
        this.recvcleBallsCount = 1;
        // 在来一次
        this.isGameOver = false;
    }
}
